package com.jumi.microservice.controller;

import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jumi.microservice.common.base.dto.BasePageResponse;
import com.jumi.microservice.common.base.dto.ResponseResult;
import com.jumi.microservice.common.constant.RequestConstant;
import com.jumi.microservice.common.core.aspect.WebLog;
import com.jumi.microservice.common.utils.ResultGenerator;
import com.jumi.microservice.constant.PriorTypeEnum;
import com.jumi.microservice.constant.RedirectType;
import com.jumi.microservice.constant.StatusEnum;
import com.jumi.microservice.domain.Log;
import com.jumi.microservice.domain.LogDetailVO;
import com.jumi.microservice.domain.OperateLogQuery;
import com.jumi.microservice.domain.Priority;
import com.jumi.microservice.domain.dto.PriorityDTO;
import com.jumi.microservice.domain.vo.PriorityRMenuVO;
import com.jumi.microservice.domain.vo.PriorityRVO;
import com.jumi.microservice.domain.vo.PriorityVO;
import com.jumi.microservice.service.AccountService;
import com.jumi.microservice.service.LogService;
import com.jumi.microservice.service.PriorityService;
import com.jumi.microservice.utils.LogObjectCopyUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 权限表 前端控制器
 * </p>
 *
 * @author liuz
 * @since 2020-07-18
 */
@RestController
@Api(tags = "权限表 相关接口")
@RequestMapping("/auth/priority")
public class PriorityController {

    @Autowired
    private PriorityService priorityService;

    @Autowired
    private AccountService accountService;

    @Autowired
    private LogService logService;

    /**
     *  数据参数改为前端需要格式
     * @param priority
     * @param username
     * @date 20200824
     * @return
     */
    @ApiOperation(value = "新增数据", notes = "新增一条权限表数据")
    @PostMapping("/add")
    @WebLog(description = "新增菜单信息")
    public ResponseResult add(@Validated @RequestBody PriorityRMenuVO priority, @RequestHeader(RequestConstant.ADMIN_NAME)String username) {
        //vo->dto
        PriorityDTO dto = vo2Dto(priority);
        //获取用户名
        dto.setCreater(username);
        dto.setModifier(username);
        priorityService.insert(dto);
        return ResultGenerator.genSuccessResult();
    }


    @ApiOperation(value = "删除数据", notes = "删除指定ID权限表数据")
    @ApiImplicitParam(name = "id", value = "ID")
    @DeleteMapping("/delete")
    @WebLog(description = "删除菜单信息")
    public ResponseResult delete(@RequestParam Long id, @RequestHeader(RequestConstant.ADMIN_NAME)String username) {
        //id 主键id username 用户名
        priorityService.delete(id, username);
        return ResultGenerator.genSuccessResult();
    }

    /**
     *  数据参数改为前端需要格式
     * @param priority
     * @param username
     * @date 20200824
     * @return
     */
    @ApiOperation(value = "更新数据", notes = "更新指定ID权限表数据")
    @PutMapping("/update")
    @WebLog(description = "编辑菜单信息")
    public ResponseResult update(@Validated @RequestBody PriorityRMenuVO priority, @RequestHeader(RequestConstant.ADMIN_NAME)String username) {
        PriorityDTO dto = vo2Dto(priority);
        //用户名
        dto.setModifier(username);
        priorityService.update(dto);
        return ResultGenerator.genSuccessResult();
    }


    @ApiOperation(value = "查询数据", notes = "获取指定ID权限表数据")
    @ApiImplicitParam(name = "id", value = "ID")
    @GetMapping("/detail")
    public ResponseResult<PriorityRMenuVO> detail(@RequestParam Long id) {
        PriorityDTO priority = priorityService.selectById(id);
        return ResultGenerator.genSuccessResult(dto2Vo(priority));
    }


    @ApiOperation(value = "启用/停用", notes = "菜单的启用/停用")
    @PostMapping("/enabled")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "主键id"),
            @ApiImplicitParam(name = "status", value = "启用状态"),
    })
    public ResponseResult enabled(@RequestParam Long id, @RequestParam Integer status) {
        priorityService.enabledStatus(id,status);
        return ResultGenerator.genSuccessResult();
    }


//    @ApiOperation(value = "查询分页", notes = "获取权限表分页列表数据")
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "page", value = "当前页码"),
//            @ApiImplicitParam(name = "size", value = "分页大小"),
//    })
//    @GetMapping("/list")
//    public BasePageResponse list(
//            @RequestParam(defaultValue = "0") Integer page,
//            @RequestParam(defaultValue = "0") Integer size,
//            PriorityVO priority) {
//        LambdaQueryWrapper<Priority> wrapper = Wrappers.lambdaQuery();
////        wrapper.like(StringUtils.isNotEmpty(priority.getPriorityName()), Priority::getPriorityName,priority.getPriorityName());
////        wrapper.eq(priority.getStatus()!=null, Priority::getStatus,priority.getStatus());
////        wrapper.ge(StringUtils.isNotEmpty(priority.getStartTimeAdd()), Priority::getCreateTime,priority.getStartTimeAdd());
////        wrapper.le(StringUtils.isNotEmpty(priority.getEndTimeAdd()), Priority::getCreateTime,priority.getEndTimeAdd());
////        wrapper.ge(StringUtils.isNotEmpty(priority.getStartTimeUp()), Priority::getUpdateTime,priority.getStartTimeUp());
////        wrapper.le(StringUtils.isNotEmpty(priority.getEndTimeUp()), Priority::getUpdateTime,priority.getEndTimeUp());
////        wrapper.eq(Priority::getIsDel, StatusEnum.STATUS_NO.getCode());
////        wrapper.orderByDesc(Priority::getOrderNum, Priority::getUpdateTime);
//        IPage<Priority> pageInfo = priorityService.page(
//                new Page<>(page, size),wrapper);
//        return ResultGenerator.genSuccessResultPage(pos2Vos(pageInfo.getRecords()),pageInfo.getTotal());
//    }

    /**
     * 查询权限列表
     *
     * @return
     */
    @GetMapping("/roots/list")
    @ApiOperation(value = "查询权限列表", notes = "查询权限列表 按名称等查询")
    public ResponseResult<List<PriorityRMenuVO>> rootList(PriorityVO vo) {
//        List<Priority> list = null;
//        if(StringUtils.isNotEmpty(vo.getPriorityName())) {
//            list = priorityService.getRootList(vo);
//        }else{
//
//        }
        //按若依直接返回
        LambdaQueryWrapper<Priority> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StringUtils.isNotEmpty(vo.getPriorityName()),Priority::getPriorityName,vo.getPriorityName());
        wrapper.eq(vo.getStatus()!=null, Priority::getStatus,vo.getStatus());
        wrapper.ge(StringUtils.isNotEmpty(vo.getStartTimeAdd()), Priority::getCreateTime,vo.getStartTimeAdd());
        wrapper.le(StringUtils.isNotEmpty(vo.getEndTimeAdd()), Priority::getCreateTime,vo.getEndTimeAdd());
        wrapper.ge(StringUtils.isNotEmpty(vo.getStartTimeUp()), Priority::getUpdateTime,vo.getStartTimeUp());
        wrapper.le(StringUtils.isNotEmpty(vo.getEndTimeUp()), Priority::getUpdateTime,vo.getEndTimeUp());
        wrapper.eq(Priority::getIsDel, StatusEnum.STATUS_NO.getCode());
        //根目录不返回
        wrapper.ne(Priority::getPriorityType,PriorTypeEnum.ROOT.getCode());
        wrapper.orderByDesc(Priority::getOrderNum, Priority::getUpdateTime);
        List<Priority> list = priorityService.list(wrapper);
        return ResultGenerator.genSuccessResult(pos2Vos(list));
    }

    @ApiOperation(value = "查询模块", notes = "获取模块分页数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "当前页码"),
            @ApiImplicitParam(name = "size", value = "分页大小"),
    })
    @GetMapping("/root")
    public ResponseResult<IPage<Priority>> root(
            @RequestParam(defaultValue = "0") Integer page,
            @RequestParam(defaultValue = "0") Integer size) {
        LambdaQueryWrapper<Priority> wrapper = Wrappers.lambdaQuery();
        //根目录不返回
        wrapper.ne(Priority::getParentId,StatusEnum.STATUS_NO.getCode());
        wrapper.eq(Priority::getPriorityType, PriorTypeEnum.ROOT.getCode());
        wrapper.eq(Priority::getIsDel,StatusEnum.STATUS_NO.getCode());
        wrapper.orderByDesc(Priority::getOrderNum, Priority::getUpdateTime);
        IPage<Priority> pageInfo = priorityService.page(
                new Page<>(page, size),wrapper);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @ApiOperation(value = "查询子权限列表", notes = "查询子权限列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "当前页码"),
            @ApiImplicitParam(name = "size", value = "分页大小"),
            @ApiImplicitParam(name = "id", value = "ID")
    })
    @GetMapping("/child")
    public ResponseResult<IPage<Priority>> child(
            @RequestParam(defaultValue = "0") Integer page,
            @RequestParam(defaultValue = "0") Integer size,
            @RequestParam Integer id) {
        LambdaQueryWrapper<Priority> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Priority::getParentId,id);
        wrapper.eq(Priority::getIsDel,0);
        wrapper.orderByDesc(Priority::getOrderNum, Priority::getUpdateTime);
        IPage<Priority> pageInfo = priorityService.page(
                new Page<>(page, size),wrapper);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @ApiOperation(value = "角色权限", notes = "新增/编辑角色获取权限")
    @ApiImplicitParam(name = "id", value = "ID")
    @GetMapping("/rolePriors")
    public JSONObject rolePriors(@RequestParam Long id) {
        JSONObject priority = priorityService.selectPriorsByRoleId(id);
        return priority;
    }

    @ApiOperation(value = "用户的权限", notes = "获取登录用户的权限")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "accountId", value = "用户id") ,
            @ApiImplicitParam(name = "pid", value = "模块或父级id ")
    })
    @GetMapping("/tree/authorized")
    public ResponseResult<List<PriorityRVO>> authorizeList(@RequestParam Long accountId, HttpServletRequest request) {
        //暂时不用 超级管理员操作
        List<PriorityRVO> priority = priorityService.authorizeList(accountId);
        return ResultGenerator.genSuccessResult(priority);
    }

    @ApiOperation(value = "用户的信息", notes = "获取登录用户的信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "accountId", value = "用户id")
    })
    @GetMapping("/getInfo")
    public JSONObject getInfo(@RequestParam Long accountId, HttpServletRequest request) {
        //暂时不用 超级管理员操作
        JSONObject o = priorityService.getInfo(accountId);
        return o;
    }

    @ApiOperation(value = "模块操作日志查询", notes = "模块操作日志查询分页列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "当前页码"),
            @ApiImplicitParam(name = "size", value = "分页大小"),
    })
    @GetMapping("/listLog")
    public BasePageResponse listLog(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "0") Integer size,
            OperateLogQuery logQuery) {
        Page<Log> list = logService.listOperateLogs(logQuery);
        //处理分页
//        if(list.size()>size){
//            return ResultGenerator.genSuccessResultPage(
//                    list.stream()
//                            .skip(size * (page - 1))
//                            .limit(size).collect(Collectors.toList())
//                    ,Long.valueOf(list.size()));
//        }
        return ResultGenerator.genSuccessResultPage(LogObjectCopyUtil.convertOperateLogDoList2VoList(list.getRecords()), list.getTotal());
    }

    /**
     * 对象转换 vo->dto
     * @param vo
     * @date 20200824 数据格式改为前端需要 若依版
     * @return
     */
    private PriorityDTO vo2Dto(PriorityRMenuVO vo){
        PriorityDTO r = new PriorityDTO();
        r.setId(vo.getMenuId());
        r.setIcon(vo.getIcon());
        r.setOrderNum(vo.getOrderNum());
        r.setParentId(vo.getParentId());
        r.setPath(vo.getPath());
        r.setPriorityCode(vo.getPerms());
        r.setPriorityName(vo.getMenuName());
        r.setPriorityType(vo.getMenuType());
        r.setStatus(vo.getStatus());
        r.setComponent(vo.getComponent());
        r.setHidden(vo.getHidden()?StatusEnum.STATUS_YES.getCode():StatusEnum.STATUS_NO.getCode());
        return r;
    }

    /**
     * 对象转换 dto->vo
     * @param dto
     * @date 20200824 数据转为前端需要格式
     * @return
     */
    private PriorityRMenuVO dto2Vo(PriorityDTO dto){
        PriorityRMenuVO r = new PriorityRMenuVO();
        r.setVisible(StatusEnum.STATUS_YES.getCode());
        r.setUpdateTime(dto.getUpdateTime());
        r.setUpdateBy(dto.getModifier());
        r.setStatus(dto.getStatus());
        r.setRedirect(RedirectType.NO_REDIRECT);
        r.setPerms(dto.getPriorityCode());
        r.setPath(dto.getPath());
        r.setParentId(dto.getParentId());
        r.setOrderNum(dto.getOrderNum());
        r.setMenuType(dto.getPriorityType());
        r.setMenuName(dto.getPriorityName());
        r.setIcon(dto.getIcon());
        r.setComponent(dto.getComponent());
        r.setCreateTime(dto.getCreateTime());
        r.setCreateBy(dto.getCreater());
        r.setMenuId(dto.getId());
        r.setHidden(dto.getHidden()==StatusEnum.STATUS_YES.getCode()?true:false);
        return r;
    }

    /**
     * 列表数据转为前端若依格式
     * @param pos
     * @date 20200824
     * @return
     */
    private List<PriorityRMenuVO> pos2Vos(List<Priority> pos){
        List<PriorityRMenuVO> vos = pos.stream().map(p->{
            PriorityRMenuVO vo = new PriorityRMenuVO();
            vo.setMenuId(p.getId());
            vo.setAlwaysShow(StatusEnum.STATUS_YES.getCode());
            vo.setComponent(p.getComponent());
            vo.setCreateBy(p.getCreater());
            vo.setCreateTime(p.getCreateTime());
            vo.setHidden(p.getHidden()==StatusEnum.STATUS_YES.getCode()?true:false);
            vo.setIcon(p.getIcon());
            vo.setIsFrame(StatusEnum.STATUS_NO.getCode());
            vo.setMenuName(p.getPriorityName());
            vo.setMenuType(p.getPriorityType());
            vo.setOrderNum(p.getOrderNum());
            vo.setParentId(p.getParentId());
            vo.setPath(p.getPath());
            vo.setPerms(p.getPriorityCode());
            vo.setRedirect(RedirectType.NO_REDIRECT);
            vo.setStatus(p.getStatus());
            vo.setUpdateBy(p.getModifier());
            vo.setUpdateTime(p.getUpdateTime());
            vo.setVisible(StatusEnum.STATUS_YES.getCode());
            return vo;
        }).collect(Collectors.toList());
        return vos;
    }
}
